package com.gmrz.uap.model;

import com.gmrz.uap.cfg.SystemConst;
import com.gmrz.uap.common.ConditionConst;
import com.gmrz.uap.common.DBCommon;
import com.gmrz.uap.model.base.BaseFidoLog;
import com.gmrz.uap.util.DateUtil;
import com.gmrz.uap.util.Encodes;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class FidoLog extends BaseFidoLog<FidoLog> {
    public static final FidoLog dao = new FidoLog();

    private static final String NAMESPACE = "fidoLog";
    private static final String SQL_SELECT_COMM = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "select_comm";
    private static final String SQL_SELECT_FIND_FIDOLOG_DATE_TENANTID_AUTHTYPE = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "fidoLogCountByDate";

    private static final String SQL_DELETE_FIDOLOG = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "deleteByGreaterThanDay";
    // 过期的日志插入到历史表中--插入时不记录日志的sql路径
    private static final String SQL_ALTER_FIDOLOGHIS = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "alterLogHisNotLog";
    // 过期的日志插入到历史表中--插入的sql路径--业务历史表中不为空
    private static final String SQL_INSERT_NOTNULL_FIDOLOGHIS = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "insertHisByGreaterThanDayAndMaxDay";
    // 过期的日志插入到历史表中--插入的sql路径--业务历史表中为空
    private static final String SQL_INSERT_FIDOLOGHIS = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "insertHisByGreaterThanDay";
    // 查询业务历史表中的最大的时间
    private static final String SQL_SELECT_MAX_CREATES_FIDOLOGHIS = NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "selectMaxCreatesOnFidoLogHis";


    /**
     * 根据页面传过来的条件进行分页查询
     *
     * @param fidoLog 业务日志信息
     * @param page    页号
     * @param rows    行数
     * @param sort    排序字段
     * @param order   升序/降序
     * @return　分页结果 Page<FidoLog>
     */
    public Page<FidoLog> findFidoLogListForPaginate(FidoLog fidoLog, int page, int rows, String sort, String order, Map<String, Object> condition) {

        fidoLog.put(SystemConst.DATATABLE_PAGINATE_OFFSET, page);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_ROWS, rows);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_SORT, sort);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_ORDER, order);
        fidoLog.put(SystemConst.DATATABLE_MAX_PAGE_COUNT_KEY, SystemConst.DATATABLE_MAX_PAGE_COUNT);

        //获取总行数
        SqlPara recordCountSql = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).getSqlPara(NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "findFidoLogListForPaginateCount", fidoLog);
        int totalRow = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryInt(recordCountSql.getSql());
        //查询到的数量小于30000则使用查询到的结果
        totalRow = (totalRow + 1) < SystemConst.DATATABLE_MAX_PAGE_COUNT ? totalRow : SystemConst.DATATABLE_MAX_PAGE_COUNT;

        //获取数据集合
        SqlPara recordListSql = this.getSqlPara(NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "findFidoLogListForPaginate", fidoLog);
        List<FidoLog> fidoLogList = this.find(recordListSql);

        //获取总页数
        int totalPage = SystemConst.getTotalPage(totalRow, rows);

        //分页数据
        return new Page<FidoLog>(fidoLogList, rows, page, totalPage, totalRow);
    }


    /**
     * 根据日期获取统计数量
     *
     * @param date
     * @return
     */
    public Integer fidoLogCountByDate(String date, String tenantId, String authType) {
//        Kv cond = Kv.by("date", date).set("tenantId", tenantId).set("authType", authType);
//        SqlPara sqlPara = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).getSqlPara(SQL_SELECT_FIND_FIDOLOG_DATE_TENANTID_AUTHTYPE, cond);
        String sql = "SELECT count(*) FROM t_fido_log WHERE createts >= ? and createts < ? AND tenant_id = ? AND oper_type in (3,9,12) AND auth_type = ?";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = null;
        try {
            d1 = simpleDateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryNumber(sql, new Date(d1.getTime()), new Date(d1.getTime() + (long) 86400000), tenantId, authType).intValue();
    }


    /**
     * 根据日期获取交易类型的数量
     *
     * @param date
     * @param tenantId
     * @param transType
     * @return
     */
    public Integer transTypeCountByDate(String date, String tenantId, String transType) {
        String sql = "select count(*) from t_fido_log where createts >= ? and createts < ? and tenant_id = ? and trans_type = ?";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = null;
        try {
            d1 = simpleDateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryNumber(sql, new Date(d1.getTime()), new Date(d1.getTime() + (long) 86400000), tenantId, transType).intValue();
    }


    /**
     * 获取表中最小的时间
     *
     * @return
     */
    public DateTime getEarliestDate() {
        DateTime dateTime;
        String minDate = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryStr(this.getSql(NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "getEarliestDate"));

        if (StrKit.isBlank(minDate)) {//如果返回为空代表数据库中还没有数据，则返回当前时间
            dateTime = new DateTime();
        } else {
            dateTime = new DateTime(minDate);
        }
        return dateTime;
    }


    /**
     * 查询大于某一天之前的记录数
     *
     * @param day 日期
     * @return 记录数
     */
    public long findByGreaterThanDay(String day) {
        String sql = "select count(*) from t_fido_log where createts < '" + day + "'";
        return Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryLong(sql);
    }

    /**
     * 删除大于某一天之前的记录
     *
     * @param day 日期
     * @return boolean
     */
    public int deleteByGreaterThanDay(String day) {

//        String sql = "delete from t_fido_log where createts < '" + day + "'";
//        return Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).delete(sql) > 0;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = simpleDateFormat.parse(day);
            int deleteCount = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).delete(getSql(SQL_DELETE_FIDOLOG), date);
            //int update = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).update(getSql(SQL_DELETE_FIDOLOG), date1);
            return deleteCount;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }



    /**
     * 将大于某一天之前的记录全部插入到历史表中
     *
     * @param day 日期
     *
     */
    public int insertHisByGreaterThanDay(String day, String maxCreatesOnFidoLogHis) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = simpleDateFormat.parse(day);
            int insertCount ;
            // 判断项目所连接数据库是否为 【db2】
            if (StringUtils.isNotBlank(SystemConst.DB_TYPE) && SystemConst.DB_TYPE_DB2.equals(SystemConst.DB_TYPE)){
                // 设置历史表不记录操作日志
                Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).update(getSql(SQL_ALTER_FIDOLOGHIS));
            }
            if (StringUtils.isNotBlank(maxCreatesOnFidoLogHis)){
                Date maxDate = simpleDateFormat.parse(maxCreatesOnFidoLogHis);
                // 将过期日志复制到历史表
                insertCount = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).update(getSql(SQL_INSERT_NOTNULL_FIDOLOGHIS), date , maxDate);
            }else {
                insertCount = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).update(getSql(SQL_INSERT_FIDOLOGHIS), date );
            }
            return insertCount;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }



    /**
     * 根据页面传过来的条件进行 业务历史日志 的分页查询
     *
     * @param fidoLog 业务日志信息
     * @param page    页号
     * @param rows    行数
     * @param sort    排序字段
     * @param order   升序/降序
     * @return　分页结果 Page<FidoLog>
     */
    public Page<FidoLog> findFidoHisLogListForPaginate(FidoLog fidoLog, int page, int rows, String sort, String order, Map<String, Object> condition) {

        fidoLog.put(SystemConst.DATATABLE_PAGINATE_OFFSET, page);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_ROWS, rows);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_SORT, sort);
        fidoLog.put(SystemConst.DATATABLE_PAGINATE_ORDER, order);
        fidoLog.put(SystemConst.DATATABLE_MAX_PAGE_COUNT_KEY, SystemConst.DATATABLE_MAX_PAGE_COUNT);

        //获取总行数
        SqlPara recordCountSql = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).getSqlPara(NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "findFidoHisLogListForPaginateCount", fidoLog);
        int totalRow = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryInt(recordCountSql.getSql());
        //查询到的数量小于30000则使用查询到的结果
        totalRow = (totalRow + 1) < SystemConst.DATATABLE_MAX_PAGE_COUNT ? totalRow : SystemConst.DATATABLE_MAX_PAGE_COUNT;

        //获取数据集合
        SqlPara recordListSql = this.getSqlPara(NAMESPACE + SystemConst._DEFAULT_SEPARATOR_DOT + "findFidoHisLogListForPaginate", fidoLog);
        List<FidoLog> fidoLogList = this.find(recordListSql);

        //获取总页数
        int totalPage = SystemConst.getTotalPage(totalRow, rows);

        //分页数据
        return new Page<FidoLog>(fidoLogList, rows, page, totalPage, totalRow);
    }

    /**
     * 去业务日志历史表中获取最大的时间
     * @return
     */
    public String findMaxCreatesOnFidoLogHis(){
        String maxCreates = null;
       try {
           maxCreates = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryStr(getSql(SQL_SELECT_MAX_CREATES_FIDOLOGHIS));
       }catch (Exception e){
           e.printStackTrace();
       }
        return maxCreates ;
    }

    public String findFidoLogInfo(String flID, String infoType) throws UnsupportedEncodingException {
        String sql = null;
        int extendType = 0;
        if("1".equals(infoType)){
            extendType = 1;
            sql = "select request,request_one,request_two,field1 from t_fido_log where fl_id = ?";
        }else if("2".equals(infoType)){
            extendType = 2;
            sql = "select response,response_one,response_two,field1 from t_fido_log where fl_id = ?";
        }
        Object[] fidoLog = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryFirst(sql,flID);
        String result = null;
        if("1".equals(fidoLog[3])){
            result = getString(fidoLog[0]) + getString(fidoLog[1]);
            List<Record> records = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).find("SELECT extend_content from t_fido_log_extend WHERE fl_id = ? and extend_type = ? ORDER BY extend_order",flID,extendType);
            if(null != records && records.size() > 0){
                for(Record record : records){
                    result = result + record.getStr("extend_content");
                }
            }
            String resultTmp = new String(Encodes.decodeBase64(result),"UTF-8");
            result = resultTmp;
        }else {
            result = getString(fidoLog[0])+ getString(fidoLog[1])+ getString(fidoLog[2]);
        }
        return result;
    }

    private String getString(Object obj){
        return null != obj ? obj.toString() : "";
    }

    public String findFidoHisLogInfo(String flID, String infoType) throws UnsupportedEncodingException {
        String sql = null;
        int extendType = 0;
        if("1".equals(infoType)){
            extendType = 1;
            sql = "select request,request_one,request_two,field1 from t_fido_log where fl_id = ?";
        }else if("2".equals(infoType)){
            extendType = 2;
            sql = "select response,response_one,response_two,field1 from t_fido_log where fl_id = ?";
        }
        Object[] fidoLog = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).queryFirst(sql,flID);
        String result = null;
        if("1".equals(fidoLog[3])){
            result = getString(fidoLog[0]) + getString(fidoLog[1]);
            List<Record> records = Db.use(SystemConst.DB_FIDOLOG_DATASOURCE).find("SELECT extend_content from t_fido_log_extend WHERE fl_id = ? and extend_type = ? ORDER BY extend_order",flID,extendType);
            if(null != records && records.size() > 0){
                for(Record record : records){
                    result = result + record.getStr("extend_content");
                }
            }
            String resultTmp = new String(Encodes.decodeBase64(result),"UTF-8");
            result = resultTmp;
        }else {
            result = getString(fidoLog[0])+ getString(fidoLog[1])+ getString(fidoLog[2]);
        }
        return result;
    }
}
